package com.atguigu.gulimall.order.listener;

import com.atguigu.gulimall.order.entity.OrderEntity;
import com.atguigu.gulimall.order.entity.to.OrderCreateTo;
import com.atguigu.gulimall.order.service.OrderService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

@RabbitListener(queues = "order.release.order.queue")
@Service
public class OrderCloneListener {

    @Autowired
    OrderService orderService;

    @RabbitHandler
    public void listener(OrderEntity entity, Channel channel, Message message) throws IOException {
        System.out.println("收到过期的订单信息：准备关闭订单："+ entity.getOrderSn());

        //判断消息是否是重新派过来的
//        Boolean redelivered = message.getMessageProperties().getRedelivered();

        try {
            orderService.closeOrder(entity);
            //关闭订单后，手动调用支付宝收单
            //防止支付过程中延迟问题，订单解锁完成，正在解锁库存时，异步通知才到
            //这边收单了，那边支付就会失败
            //alipay.trade.close(统一收单交易关闭接口)
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
//            e.printStackTrace();
            //异常拒收消息，返回队列
            channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
        }
    }

    //TODO 保存消息一定会发送出去，方式消息丢失
    /**
     * 消息发送出去，由于网络原因没有抵达服务器
     * 解决：做好try catch，将没发送成功的消息进行重试发送
     *  每个消息做好日志记录(在数据库保存好每一个消息的详细信息)
     *
     *  消息抵达Broker ，Broker要将消息写入磁盘持久化才算成功。此时
     *  Borker尚未持久化完成，服务器死机了，消息丢失
     *  解决：开启消息确认机制，确认成功的消息，修改数据库消息状态 见：MyRabbitConfig的initRabbitTemplate
     *
     *  自动ACK状态下，消费者收到消息，但还没来得及处理就死机
     *  解决：开启消息手动确认机制，只有消费成功了才ack
     */

    //TODO 消息重复消费
    /**
     * 消费者接收到消息后，处理完业务，还没来得及手动ack消息，就死机了--这种重复消费不影响业务
     * 消息消费失败，由于重试机制，自动又将消息发送出去--正常
     * 以上两种只要在业务逻辑上做好判断，消费接口应设计为幂等性
     */

    //TODO 消息积压
    /**
     * --消费者死机导致积压
     * --消费者消费能力不足
     * --发送者发送流量太大
     *    解决：上线更多消费者，进行正常消费
     *         上线专门的队列消息服务，将消息先批量取出来，记录到数据库，离线慢慢处理
     */
}
